// -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	DisposableBase.cs
//  Developer:	Igor Solomatov
//  Created:	02.03.2013
// 
// -------------------- iSharePoint -------------------- //

using System;
using System.Threading;

namespace Smart
{
	/// <summary>
	/// Disposable base class
	/// </summary>
	public abstract class Disposable : IDisposable
	{
		/// <summary>
		/// Flag whether class were disposed
		/// </summary>
		private int _disposed;

		/// <summary>
		/// Dispose underlying resources
		/// </summary>
		protected abstract void RealDispose();

		/// <summary>
		/// Dispose underlying resources
		/// </summary>
		public void Dispose()
		{
			if (Interlocked.CompareExchange(ref _disposed, 1, 0) != 0) return;

			RealDispose();
		}
	}

	/// <summary>
	/// Disposable base class
	/// </summary>
	public abstract class DisposableBase : Disposable
	{
		/// <summary>
		/// Dispose underlying resources
		/// </summary>
		/// <param name="disposing">flag whether method called by user directly</param>
		protected virtual void Dispose(bool disposing)
		{
			if (disposing)
			{
				DisposeManaged();
			}

			DisposeUnmanaged();
		}

		/// <summary>
		/// Dispose managed resources. Method called only once.
		/// </summary>
		protected abstract void DisposeManaged();

		/// <summary>
		/// Dispose unmanaged resources. Method called only once.
		/// </summary>
		protected abstract void DisposeUnmanaged();

		/// <summary>
		/// Dispose underlying resources
		/// </summary>
		protected override void RealDispose()
		{
			Dispose(true);

			GC.SuppressFinalize(this);
		}

		~DisposableBase()
		{
			Dispose(false);
		}
	}
}